package com.rome.hotel.data.service.impl;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import com.rome.hotel.data.domain.HotelOrder;
import com.rome.hotel.data.domain.HotelRoom;
import com.rome.hotel.data.mapper.HotelOrderMapper;
import com.rome.hotel.data.mapper.HotelRoomMapper;
import com.rome.hotel.data.utils.RegexUtils;
import com.rome.hotel.data.utils.SnowFlake;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rome.hotel.data.mapper.HotelReserveMapper;
import com.rome.hotel.data.domain.HotelReserve;
import com.rome.hotel.data.service.IHotelReserveService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 预定Service业务层处理
 * 
 * @author rome
 * @date 2024-01-20
 */
@Service
public class HotelReserveServiceImpl implements IHotelReserveService 
{
    @Autowired
    private HotelReserveMapper hotelReserveMapper;

    @Autowired
    private HotelOrderMapper hotelOrderMapper;

    @Autowired
    private HotelRoomMapper hotelRoomMapper;

    /**
     * 查询预定
     * 
     * @param reserveId 预定主键
     * @return 预定
     */
    @Override
    public HotelReserve selectHotelReserveByReserveId(Long reserveId)
    {
        return hotelReserveMapper.selectHotelReserveByReserveId(reserveId);
    }

    /**
     * 查询预定列表
     * 
     * @param hotelReserve 预定
     * @return 预定
     */
    @Override
    public List<HotelReserve> selectHotelReserveList(HotelReserve hotelReserve)
    {
//        每次查询前看看是否退房时间小于今天，如果是将状态改为已退房
        HotelReserve hotelReserveBycheeckOut = new HotelReserve();
        Date date = new Date();
        date.setHours(12);
        date.setMinutes(0);
        date.setSeconds(0);
        hotelReserveBycheeckOut.setCheckOutTime(date);
        List<HotelReserve> hotelReserves = hotelReserveMapper.selectHotelReserveQueryByCheckOutNotRoomNumber(hotelReserveBycheeckOut);
        for (HotelReserve item:hotelReserves
             ) {
            item.setJoinState("2");
           updateHotelReserve(item);
        }
        return hotelReserveMapper.selectHotelReserveList(hotelReserve);
    }

    /**
     * 新增预定
     * 
     * @param hotelReserve 预定
     * @return 结果
     */
    @Transactional
    @Override
    public String insertHotelReserve(HotelReserve hotelReserve)
    {
//        防御性编程
        Assert.notNull(hotelReserve,"参数异常");
        Assert.notNull(hotelReserve.getRoomNumber(),"房间号不能为空");
        Assert.notNull(hotelReserve.getCustomerName(),"客户姓名不能为空");
        Assert.notNull(hotelReserve.getJoinState(),"入住状态不能为空");
        Assert.notNull(hotelReserve.getGender(),"性别不能为空");
        Assert.notNull(hotelReserve.getPhoneNumber(),"手机号不能为空");
        Assert.notNull(hotelReserve.getIdCard(),"身份证不能为空");
        Assert.notNull(hotelReserve.getJoinTime(),"入住时间不能为空");
        Assert.notNull(hotelReserve.getCheckOutTime(),"退房时间不能为空");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getRoomNumber()),"房间号不能超过50位");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getCustomerName()),"客户姓名不能超过50位");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getJoinState()),"入住状态不能超过50位");
        Assert.state(hotelReserve.getGender().length()==1,"性别参数异常");
        Assert.state(RegexUtils.testPhoneNumber(hotelReserve.getPhoneNumber()),"请输入规范的手机号");
        Assert.state(RegexUtils.testIdCards(hotelReserve.getIdCard()),"请输入规范的身份证");
        Assert.state(hotelReserve.getJoinTime().before(hotelReserve.getCheckOutTime()),"入住时间要在离开时间之前");
        //查询预约时间是否已被预约
        HotelReserve hotelReserveQuery = new HotelReserve();
        hotelReserveQuery.setRoomNumber(hotelReserve.getRoomNumber());
        hotelReserveQuery.setJoinTime(hotelReserve.getJoinTime());
        hotelReserveQuery.setCheckOutTime(hotelReserve.getCheckOutTime());
        List<HotelReserve> hotelReserves = selectHotelReserveListQuerytime(hotelReserveQuery);
        Assert.state(hotelReserves.size()==0,"这个时间已被预定");
//        设置订单号
//        生成订单号
        String orderId = new SnowFlake(0, 0).createOrderNo();
        hotelReserve.setOrderNumber(orderId);
        //拿到房间价格的后面添加订单
        HotelRoom hotelRoom = hotelRoomMapper.selectHotelRoomByRoomNumber(hotelReserve.getRoomNumber());
//        查询订单中是否包含这个订单号，如果包含说明这个订单已存入订单表
            HotelOrder hotelOrder = new HotelOrder();
            hotelOrder.setOrderId(orderId);
//            通过订单号查询订单表是否存在这个订单
        List<HotelOrder> hotelOrders = hotelOrderMapper.selectHotelOrderList(hotelOrder);
//        判断这个订单号是否存在，如果不存在就添加
        if(hotelOrders.size()==0){
            hotelOrder.setAmount(hotelRoom.getRoomDiscountPrice());
            hotelOrder.setOrderStatus(hotelReserve.getJoinState());
            LocalDate currentDate = LocalDate.now();
            Calendar calendar   =   Calendar.getInstance();
            calendar.set(currentDate.getYear(),currentDate.getMonthValue()-1,currentDate.getDayOfMonth(),0,0,0);
            hotelOrder.setCreationTime(calendar.getTime());
            hotelOrderMapper.insertHotelOrder(hotelOrder);
        }
        hotelReserveMapper.insertHotelReserve(hotelReserve);
        return hotelReserve.getOrderNumber();
    }

    /**
     * 修改预定
     * 
     * @param hotelReserve 预定
     * @return 结果
     */
    @Transactional
    @Override
    public int updateHotelReserve(HotelReserve hotelReserve)
    {
        //        防御性编程
        Assert.notNull(hotelReserve,"参数异常");
        Assert.notNull(hotelReserve.getRoomNumber(),"房间号不能为空");
        Assert.notNull(hotelReserve.getCustomerName(),"客户姓名不能为空");
        Assert.notNull(hotelReserve.getJoinState(),"入住状态不能为空");
        Assert.notNull(hotelReserve.getGender(),"性别不能为空");
        Assert.notNull(hotelReserve.getPhoneNumber(),"手机号不能为空");
        Assert.notNull(hotelReserve.getIdCard(),"身份证不能为空");
        Assert.notNull(hotelReserve.getJoinTime(),"入住时间不能为空");
        Assert.notNull(hotelReserve.getCheckOutTime(),"退房时间不能为空");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getRoomNumber()),"房间号不能超过50位");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getCustomerName()),"客户姓名不能超过50位");
        Assert.state(RegexUtils.testStringNoWuShi(hotelReserve.getJoinState()),"入住状态不能超过50位");
        Assert.state(hotelReserve.getGender().length()==1,"性别参数异常");
        Assert.state(RegexUtils.testPhoneNumber(hotelReserve.getPhoneNumber()),"请输入规范的手机号");
        Assert.state(RegexUtils.testIdCards(hotelReserve.getIdCard()),"请输入规范的身份证");
        Assert.state(hotelReserve.getJoinTime().before(hotelReserve.getCheckOutTime()),"入住时间要在离开时间之前");
        //查询预约时间是否已被预约
        HotelReserve hotelReserveQuery = new HotelReserve();
        hotelReserveQuery.setRoomNumber(hotelReserve.getRoomNumber());
        hotelReserveQuery.setJoinTime(hotelReserve.getJoinTime());
        hotelReserveQuery.setCheckOutTime(hotelReserve.getCheckOutTime());
        List<HotelReserve> hotelReserves = selectHotelReserveListQuerytime(hotelReserveQuery);
//        等于0说明这个时间段没人预约，等于1说明是自己
        if(hotelReserves.size()==0){
            int result = hotelReserveMapper.updateHotelReserve(hotelReserve);
            HotelOrder queryByOrderNumber = new HotelOrder();
            queryByOrderNumber.setOrderId(hotelReserve.getOrderNumber());
            List<HotelOrder> hotelOrders = hotelOrderMapper.selectHotelOrderList(queryByOrderNumber);
//            如果查询出来的值长度为0说明订单表中不存在这个订单，创建一个订单
            if(hotelOrders.size()==0){
                HotelOrder hotelOrder = new HotelOrder();
                hotelOrder.setOrderId(hotelReserve.getOrderNumber());
                //拿到房间价格
                HotelRoom hotelRoom = hotelRoomMapper.selectHotelRoomByRoomNumber(hotelReserve.getRoomNumber());
                hotelOrder.setAmount(hotelRoom.getRoomPrice());
                hotelOrder.setOrderStatus(hotelReserve.getJoinState());
                LocalDate currentDate = LocalDate.now();
                Calendar calendar   =   Calendar.getInstance();
                calendar.set(currentDate.getYear(),currentDate.getMonthValue()-1,currentDate.getDayOfMonth(),0,0,0);
                hotelOrder.setCreationTime(calendar.getTime());
                hotelOrderMapper.insertHotelOrder(hotelOrder);
            }
            else {
                HotelOrder hotelOrder = hotelOrders.get(0);
                //拿到房间价格
                HotelRoom hotelRoom = hotelRoomMapper.selectHotelRoomByRoomNumber(hotelReserve.getRoomNumber());
                hotelOrder.setAmount(hotelRoom.getRoomPrice());
                hotelOrder.setOrderStatus(hotelReserve.getJoinState());
                hotelOrderMapper.updateHotelOrder(hotelOrder);
            }
            return result;
        }
        if(hotelReserves.size()==1&&hotelReserve.getReserveId()==hotelReserves.get(0).getReserveId()){
            int result = hotelReserveMapper.updateHotelReserve(hotelReserve);
            HotelOrder queryByOrderNumber = new HotelOrder();
            queryByOrderNumber.setOrderId(hotelReserve.getOrderNumber());
            List<HotelOrder> hotelOrders = hotelOrderMapper.selectHotelOrderList(queryByOrderNumber);
//            如果查询出来的值长度为0说明订单表中不存在这个订单，创建一个订单
            if(hotelOrders.size()==0){
                HotelOrder hotelOrder = new HotelOrder();
                hotelOrder.setOrderId(hotelReserve.getOrderNumber());
                //拿到房间价格
                HotelRoom hotelRoom = hotelRoomMapper.selectHotelRoomByRoomNumber(hotelReserve.getRoomNumber());
                hotelOrder.setAmount(hotelRoom.getRoomPrice());
                hotelOrder.setOrderStatus(hotelReserve.getJoinState());
                LocalDate currentDate = LocalDate.now();
                Calendar calendar   =   Calendar.getInstance();
                calendar.set(currentDate.getYear(),currentDate.getMonthValue()-1,currentDate.getDayOfMonth(),0,0,0);
                hotelOrder.setCreationTime(calendar.getTime());
                hotelOrderMapper.insertHotelOrder(hotelOrder);
            }
            else {
                HotelOrder hotelOrder = hotelOrders.get(0);
                //拿到房间价格
                HotelRoom hotelRoom = hotelRoomMapper.selectHotelRoomByRoomNumber(hotelReserve.getRoomNumber());
                hotelOrder.setAmount(hotelRoom.getRoomPrice());
                hotelOrder.setOrderStatus(hotelReserve.getJoinState());
                hotelOrderMapper.updateHotelOrder(hotelOrder);
            }
            return result;
        }
        return 0;
    }

    /**
     * 批量删除预定
     * 
     * @param reserveIds 需要删除的预定主键
     * @return 结果
     */
    @Override
    public int deleteHotelReserveByReserveIds(Long[] reserveIds)
    {
        return hotelReserveMapper.deleteHotelReserveByReserveIds(reserveIds);
    }

    /**
     * 删除预定信息
     * 
     * @param reserveId 预定主键
     * @return 结果
     */
    @Override
    public int deleteHotelReserveByReserveId(Long reserveId)
    {
        return hotelReserveMapper.deleteHotelReserveByReserveId(reserveId);
    }

    /**
     * 根据时间查询是否在预约时间和退房时间
     * @return
     */
    public  List<HotelReserve> selectHotelReserveListQuerytime(HotelReserve hotelReserve){
        return hotelReserveMapper.selectHotelReserveListQuerytime(hotelReserve);
    }
    /**
     * 根据时间查询预约时间在今天之后的房间
     * @return
     */
    public  List<HotelReserve> selectHotelReserveQueryByCheckOut(HotelReserve hotelReserve){
        return hotelReserveMapper.selectHotelReserveQueryByCheckOut(hotelReserve);
    }
    /**
     * 根据入住时间查询
     */
    public  List<HotelReserve> selectHotelReserveByJoinTime(HotelReserve hotelReserve){
        return hotelReserveMapper.selectHotelReserveByJoinTime(hotelReserve);
    }
    /**
     * 批量查询订单号
     *
     * @param orderNumbers
     * @return 结果
     */
    public List<HotelReserve> selectHotelReserveByorderNumbers(String[] orderNumbers){
        return hotelReserveMapper.selectHotelReserveByorderNumbers(orderNumbers);
    }

    /**
     * 查询订单号
     *
     * @param orderNumber
     * @return 结果
     */
    public HotelReserve selectHotelReserveByOrderNumber(String orderNumber){
        return hotelReserveMapper.selectHotelReserveByOrderNumber(orderNumber);
    }
}
